package com.baiye.www.channel;

import com.baiye.www.config.Config;
import com.baiye.www.protocol.MessageCodec;
import com.baiye.www.protocol.ProcotolFrameDecoder;
import com.baiye.www.proxyHandler.RpcResponseMessageHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * @author GUOZHIPENG
 * @version 1.0
 * @date 2021/12/1 21:11
 */
@Slf4j
public class ChannelContainer {
    private static Channel channel = null;
    private static final Object LOCK = new Object();

    public static Channel getChannel(){
        if(channel!=null){
            return channel;
        }else {
            synchronized (LOCK){
                if(channel!=null){
                    return channel;
                }else {
                    initChannel();
                    return channel;
                }
            }
        }
    }

    private static void initChannel() {
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
        LoggingHandler loggingHandler = new LoggingHandler(LogLevel.DEBUG);
        MessageCodec messageCodec = new MessageCodec();
        RpcResponseMessageHandler rpcResponseMessageHandler = new RpcResponseMessageHandler();
        Bootstrap bootstrap=new Bootstrap();
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.group(nioEventLoopGroup).handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {

                socketChannel.pipeline().addLast(new ProcotolFrameDecoder());
                socketChannel.pipeline().addLast(loggingHandler);
                socketChannel.pipeline().addLast(messageCodec);
                socketChannel.pipeline().addLast(rpcResponseMessageHandler);

            }
        });
        try {
            channel=bootstrap.connect(Config.IP, Config.PORT).sync().channel();
            channel.closeFuture().addListener((future -> {
                nioEventLoopGroup.shutdownGracefully();
            }));
        } catch (InterruptedException e) {
            log.error("channel create or shutdown error");
            e.printStackTrace();
        }
    }
}
